package qrcodeutil

import (
	"archive/zip"
	"image"
	"image/png"
	"io"
	"os"
)

// SaveQRCodeImage 函数用于保存生成的二维码图像到文件。
// 参数 fileName 指定保存的文件路径，img 是要保存的图像。
// 函数返回可能的错误，例如创建文件或编码图像时的错误。
func SaveQRCodeImage(fileName string, img image.Image) error {
	// 创建文件，如果文件已存在则覆盖
	file, err := os.Create(fileName)
	if err != nil {
		return err
	}
	defer file.Close() // 在函数返回前关闭文件

	// 使用 PNG 编码将图像保存到文件中
	err = png.Encode(file, img)
	if err != nil {
		return err
	}

	return nil
}

// ZipFiles 函数用于将指定目录中的文件打包成一个压缩文件。
// 参数 zipFileName 指定压缩文件的名称，sourceDir 是要压缩的目录。
// 函数返回可能的错误，例如创建文件或添加文件到压缩包时的错误。
func ZipFiles(zipFileName, sourceDir string) error {
	// 创建压缩文件
	zipFile, err := os.Create(zipFileName)
	if err != nil {
		return err
	}
	defer zipFile.Close() // 在函数返回前关闭文件

	// 创建 zip.Writer
	zipWriter := zip.NewWriter(zipFile)
	defer zipWriter.Close() // 在函数返回前关闭 zip.Writer

	// 将指定目录中的文件添加到压缩包
	err = addFilesToZip(zipWriter, sourceDir, "")
	if err != nil {
		return err
	}

	return nil
}

// addFilesToZip 函数用于将指定目录中的文件及子目录添加到 zip.Writer 中。
// 参数 zipWriter 是 zip.Writer 对象，basePath 是要添加到压缩包的目录路径，
// baseInZip 是在压缩包中的相对路径。函数返回可能的错误，例如读取文件或创建 zip 文件时的错误。
func addFilesToZip(zipWriter *zip.Writer, basePath, baseInZip string) error {
	// 读取目录下的所有文件和子目录
	files, err := os.ReadDir(basePath)
	if err != nil {
		return err
	}

	// 遍历目录下的文件和子目录
	for _, file := range files {
		fullPath := basePath + "/" + file.Name()
		if file.IsDir() {
			// 如果是子目录，递归调用 addFilesToZip 处理子目录
			err = addFilesToZip(zipWriter, fullPath, baseInZip+file.Name()+"/")
			if err != nil {
				return err
			}
		} else {
			// 如果是文件，打开文件并创建相应的 zip.Writer 条目
			file, err := os.Open(fullPath)
			if err != nil {
				return err
			}
			defer file.Close()

			writer, err := zipWriter.Create(baseInZip + file.Name())
			if err != nil {
				return err
			}

			// 将文件内容拷贝到 zip.Writer 条目中
			_, err = io.Copy(writer, file)
			if err != nil {
				return err
			}
		}
	}

	return nil
}
